﻿
namespace n_USBASP
{
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

using n_CodeBox;
using n_CPUType;
using n_ISP;
using n_ISPSystemData;
using n_USBASP_LaterFileForm;
using T;
using n_OS;

public partial class ISPForm : Form
{
	string CurrentFile;
	public DateTime LastWriteTime;
	bool isLoad;
	
	Image AutoIcon;
	Image OpenFileIcon;
	Image LaterFileIcon;
	Image ReloadFileIcon;
	
	Image[] men;
	int menIndex;
	
	Image[] sound;
	int soundIndex;
	
	//近期文件列表
	LaterHexFileForm LaterFileBox;
	
	bool isSelf;
	
	//构造函数
	public ISPForm( bool IsSelf )
	{
		InitializeComponent();
		this.MinimumSize = this.Size;
		this.MaximumSize = this.Size;
		
		isSelf = IsSelf;
		isLoad = false;
		
		//配置数据管理器初始化
		SystemData.Init();
		SystemData.Load();
		
		//设置下载类
		ISP.SetProgress( this.progressBar1 );
		
		//设置锁定信息
		SetLockMessage( "null" );
		//输出信息初始化
		OutputBox.Init( this.label14 );
		//代码文本初始化
		CodeBox.Init( this.CodeText, this.LineLabel );
		//初始化检查框
		InitCheckBox();
		//近期文件列表
		LaterFileBox = new LaterHexFileForm();
		
		AutoIcon = Image.FromFile( OS.SystemRoot + "Resource" + OS.PATH_S + "下载器" + OS.PATH_S + "图标" + OS.PATH_S + "Auto.ico" );
		OpenFileIcon = Image.FromFile( OS.SystemRoot + "Resource" + OS.PATH_S + "下载器" + OS.PATH_S + "图标" + OS.PATH_S + "OpenFile.ico" );
		LaterFileIcon = Image.FromFile( OS.SystemRoot + "Resource" + OS.PATH_S + "下载器" + OS.PATH_S + "图标" + OS.PATH_S + "LaterFile.ico" );
		ReloadFileIcon = Image.FromFile( OS.SystemRoot + "Resource" + OS.PATH_S + "下载器" + OS.PATH_S + "图标" + OS.PATH_S + "ReloadFile.ico" );
		
		//小人
		menIndex = 0;
		men = new Image[ 7 ];
		for( int i = 0; i < men.Length; ++i ) {
			men[ i ] = Image.FromFile( OS.SystemRoot +
			                          "Resource" + OS.PATH_S + "下载器" + OS.PATH_S + "图标" + OS.PATH_S + "animen0" + ( i + 1 ) + ".ico" );
		}
		//小喇叭
		soundIndex = 0;
		sound = new Image[ 5 ];
		for( int i = 0; i < sound.Length; ++i ) {
			sound[ i ] = Image.FromFile( OS.SystemRoot +
			                          "Resource" + OS.PATH_S + "下载器" + OS.PATH_S + "图标" + OS.PATH_S + "audio" + ( i + 1 ) + ".ico" );
		}
		this.芯片选择comboBox.SelectedIndex = 0;
		
		isLoad = true;
	}
	
	//运行
	public void Run()
	{
		this.Visible = true;
		this.Activate();
	}
	
	//打开一个文件
	public void LoadHexFile( string FileName )
	{
		if( FileName == null ) {
			return;
		}
		if( !File.Exists( FileName ) ) {
			MessageBox.Show( "不存在的文件: " + FileName );
			return;
		}
		//打开选择的文件
		string text = VIO.OpenTextFile( FileName );
		LastWriteTime = File.GetLastWriteTime( FileName );
		
		//添加到近期文档列表
		LaterFileBox.AddFile( FileName );
		
		OutputBox.ShowMessage( "已载入文件: " + FileName );
		SetLockMessage( FileName );
		CodeBox.SetCodeText( text );
	}
	
	//设置芯片类型
	public void SetChipType( string ChipType )
	{
		MessageBox.Show( "ISP下载窗体暂不支持根据程序芯片类型自动设置目标芯片类型, 请手动设置为: " + ChipType );
		return;
		
//		switch( ChipType ) {
//			case CPUType.MCS51: ChipList.SetChip( "AT89S52" ); 芯片选择comboBox.SelectedIndex = 1; return;
//			case CPUType.MEGA48: ChipList.SetChip( "MEGA48" ); 芯片选择comboBox.SelectedIndex = 2; return;
//			case CPUType.MEGA8: ChipList.SetChip( "MEGA8" ); 芯片选择comboBox.SelectedIndex = 3; return;
//			case CPUType.MEGA16: ChipList.SetChip( "MEGA16" ); 芯片选择comboBox.SelectedIndex = 4; return;
//			case CPUType.MEGA32: ChipList.SetChip( "MEGA32" ); 芯片选择comboBox.SelectedIndex = 5; return;
//			case null: return;
//		}
//		MessageBox.Show( "错啦,未知的芯片类型: " + ChipType );
	}
	
	//设置文件锁定信息
	public void SetLockMessage( string FileName )
	{
		if( FileName == "null" ) {
			label10.Text = "未锁定文件,缓冲区没有数据";
			label13.Text = "未锁定文件,缓冲区没有数据";
			CurrentFile = null;
		}
		else if( FileName == "readflash" ) {
			label10.Text = "未锁定文件,缓冲区数据从芯片中读取";
			label13.Text = "未锁定文件,缓冲区数据从芯片中读取";
			CurrentFile = null;
		}
		else if( FileName == "changed" ) {
			label10.Text = "未锁定文件,缓冲区数据已经被修改";
			label13.Text = "未锁定文件,缓冲区数据已经被修改";
			CurrentFile = null;
		}
		else {
			int n = FileName.LastIndexOf( OS.PATH_S );
			string Name = FileName.Remove( 0, n + 1 );
			label10.Text = "来自文件: " + Name + " (" + FileName + ")";
			label13.Text = "已锁定文件: " + Name + " (" + FileName + ")";
			CurrentFile = FileName;
		}
	}
	
	//自动操作
	public void Auto()
	{
		try {
		OutputBox.ShowMessage( "开始自动操作" );
		//开始USB通信
		string m = USB.StartDevice();
		if( m != null ) {
			//MessageBox.Show( m );
			A.CodeErrBox.Run( m );
			OutputBox.ShowMessage( m );
			return;
		}
		//数据改变重载
		if( this.DataChangeBox.Checked ) {
			OutputBox.ShowMessage( "检查文件变化..." );
			if( CurrentFile == null ) {
				MessageBox.Show( "请先打开一个文件" );
				OutputBox.ShowMessage( "载入文件失败!" );
				USB.CloseDevice();
				return;
			}
			if( LastWriteTime != System.DateTime.MinValue ) {
				DateTime Time = File.GetLastWriteTime( CurrentFile );
				if( Time != LastWriteTime ) {
					LastWriteTime = Time;
					
					string text = VIO.OpenTextFile( CurrentFile );
					OutputBox.ShowMessage( "文件改变,已重新载入" );
					SetLockMessage( CurrentFile );
					CodeBox.SetCodeText( text );
				}
			}
		}
		//比较芯片ID是否一致
		if( this.CheckIDBox.Checked ) {
			OutputBox.ShowMessage( "比较芯片ID..." );
			Chip chip = ChipList.GetSelectedChip();
			byte[] ID = null;
			int ErrorTime = 0;
			int MaxTime = 4;
			do {
				if( ErrorTime > 0 ) {
					USB.CloseDevice();
					System.Threading.Thread.Sleep( 300 );
					string mm = USB.StartDevice();
					System.Threading.Thread.Sleep( 300 );
				}
				try {
					ID = ISP.ReadChipID();
				}
				catch {
					//MessageBox.Show( "读取ID异常,请重新插入下载线" );
					A.CodeErrBox.Run( "读取ID异常,请重新插入下载线" );
					OutputBox.ShowMessage( "编程中止, 读取ID异常" );
					USB.CloseDevice();
					return;
				}
				++ErrorTime;
				if( ErrorTime > MaxTime ) {
					//MessageBox.Show( "当前芯片和目标板芯片ID不同" );
					A.CodeErrBox.Run(  "当前芯片和目标板芯片ID不同: " + ID[ 0 ] + "," + ID[ 0 ] + "," + ID[ 0 ] + " - " + chip.ChipID1 + "," + chip.ChipID2 + "," + chip.ChipID3 );
					OutputBox.ShowMessage( "编程中止, 当前芯片和目标板芯片ID不同" );
					USB.CloseDevice();
					return;
				}
			}
			while( ID[ 0 ] != chip.ChipID1 || ID[ 1 ] != chip.ChipID2 || ID[ 2 ] != chip.ChipID3 );
		}
		//擦除芯片
		if( this.EraseBox.Checked ) {
			OutputBox.ShowMessage( "擦除芯片..." );
		    ISP.Erase();
		}
		//芯片查空
		if( this.CheckEmptyBox.Checked ) {
			OutputBox.ShowMessage( "检查空片..." );
			if( !ISP.CheckEmpty() ) {
				MessageBox.Show( "空片检查失败, 不是空芯片" );
				OutputBox.ShowMessage( "编程中止, 空片检查失败" );
				USB.CloseDevice();
				return;
			}
		}
		//写入Flash
		if( this.WriteFlashBox.Checked ) {
			if( CodeBox.BufferIsEmpty() ) {
				MessageBox.Show( "缓冲区数据空! 请先打开一个文件" );
				OutputBox.ShowMessage( "缓冲区数据空! 请先打开一个文件" );
				USB.CloseDevice();
				return;
			}
			OutputBox.ShowMessage( "下载程序..." );
			ISP.WriteFlash( CodeBox.GetText() );
		}
		//校验Flash
		if( this.CheckFlashBox.Checked ) {
			OutputBox.ShowMessage( "校验..." );
			if( CodeBox.BufferIsEmpty() ) {
				MessageBox.Show( "缓冲区数据空! 请先打开一个文件" );
				OutputBox.ShowMessage( "缓冲区数据空! 请先打开一个文件" );
				USB.CloseDevice();
				return;
			}
			if( ISP.CheckFlash( CodeBox.GetText() ) ) {
				OutputBox.ShowMessage( "校验完成, 数据一致" );
			}
			else {
				string Mes = "数据校验出错!";
				MessageBox.Show( Mes );
				OutputBox.ShowMessage( Mes );
			}
		}
		//关闭USB设备
		USB.CloseDevice();
		OutputBox.ShowMessage( "自动操作完成" );
		}catch(Exception e) {
			MessageBox.Show( e.ToString() );
		}
	}
	
	//打开最后的文件(未用--在窗体装载中)
	void OpenLaterFile( object sender, EventArgs e )
	{
		string FileName = LaterFileBox.GetLatestFile();
		if( FileName == null || !File.Exists( FileName ) ) {
			return;
		}
		string text = VIO.OpenTextFile( FileName );
		OutputBox.ShowMessage( "已载入文件: " + FileName );
		SetLockMessage( FileName );
		LastWriteTime = File.GetLastWriteTime( FileName );
		CodeBox.SetCodeText( text );
	}
	
	//初始化检查框
	void InitCheckBox()
	{
		this.DataChangeBox.Checked = SystemData.ChangeLoad;
		this.CheckIDBox.Checked = SystemData.CheckID;
		this.EraseBox.Checked = SystemData.EraseFlash;
		this.CheckEmptyBox.Checked = SystemData.CheckEmpty;
		this.WriteFlashBox.Checked = SystemData.WriteFlash;
		this.CheckFlashBox.Checked = SystemData.CheckFlash;
	}
	
	//打开文件
	void OpenFileButton_Click(object sender, EventArgs e)
	{
		OpenFileDialog open = new OpenFileDialog();
		open.Filter = "机器码文件 HEX|*.HEX";
		open.Title = "请选择一个机器码文件(HEX)";
		
		if( open.ShowDialog() == DialogResult.OK ) {
			LoadHexFile( open.FileName );
		}
	}
	
	//重载文件
	void Button4Click(object sender, EventArgs e)
	{
		if( CurrentFile == null ) {
			MessageBox.Show( "请先打开一个文件" );
			OutputBox.ShowMessage( "没有锁定文件,无法重载" );
			return;
		}
		if( !File.Exists( CurrentFile ) ) {
			MessageBox.Show( "文件不存在: " + CurrentFile );
			OutputBox.ShowMessage( "载入文件失败!" );
			return;
		}
		string text = VIO.OpenTextFile( CurrentFile );
		OutputBox.ShowMessage( "已载入文件: " + CurrentFile );
		SetLockMessage( CurrentFile );
		LastWriteTime = File.GetLastWriteTime( CurrentFile );
		CodeBox.SetCodeText( text );
	}
	
	//读取Flash
	void ReadFlashButton_Click(object sender, EventArgs e)
	{
		OutputBox.ShowMessage( "正在读Flash..." );
		//打开USB设备
		string m = USB.StartDevice();
		if( m != null ) {
			MessageBox.Show( m );
			OutputBox.ShowMessage( m );
			return;
		}
		//读取Flash
		ISP.ReadFlash();
		//关闭USB设备
		USB.CloseDevice();
		OutputBox.ShowMessage( "Flash读取完成" );
		SetLockMessage( "readflash" );
	}
	
	//芯片擦除
 	void EraseButton_Click(object sender, EventArgs e)
	{
 		OutputBox.ShowMessage( "正在擦除芯片..." );
		//开始USB通信
		string m = USB.StartDevice();
		if( m != null ) {
			MessageBox.Show( m );
			OutputBox.ShowMessage( m );
			return;
		}
		ISP.Erase();
		USB.CloseDevice();
		OutputBox.ShowMessage( "芯片已擦除" );
	}
	
	//写入Flash
	void WriteFlashButton_Click(object sender, EventArgs e)
	{
		OutputBox.ShowMessage( "正在写入Flash..." );
		if( CodeBox.BufferIsEmpty() ) {
			MessageBox.Show( "缓冲区数据空! 请先打开一个文件" );
			OutputBox.ShowMessage( "缓冲区数据空! 请先打开一个文件" );
			return;
		}
		//开始USB通信
		string m = USB.StartDevice();
		if( m != null ) {
			MessageBox.Show( m );
			OutputBox.ShowMessage( m );
			return;
		}
		//写入Flah
		ISP.WriteFlash( CodeBox.GetText() );
		//关闭USB设备
		USB.CloseDevice();
		OutputBox.ShowMessage( "Flash写入完成" );
	}
    
	//检查空片
	void CheckEmptyButtonClick(object sender, EventArgs e)
	{
		OutputBox.ShowMessage( "正在检查空片..." );
		
		//打开USB设备
		string m = USB.StartDevice();
		if( m != null ) {
			MessageBox.Show( m );
			OutputBox.ShowMessage( m );
			return;
		}
		//检查芯片是否空
		if( ISP.CheckEmpty() ) {
			OutputBox.ShowMessage( "空片检查完成, 芯片空白" );
		}
		else {
			string Mes = "空片检查失败, 芯片非空.";
			MessageBox.Show( Mes );
			OutputBox.ShowMessage( Mes );
		}
		//关闭USB设备
		USB.CloseDevice();
	}
	
	//校验Flash
	void CheckFlashButtonClick(object sender, EventArgs e)
	{
		OutputBox.ShowMessage( "正在校验Flash..." );
		
		if( CodeBox.BufferIsEmpty() ) {
			MessageBox.Show( "缓冲区数据空! 请先打开一个文件" );
			OutputBox.ShowMessage( "缓冲区数据空! 请先打开一个文件" );
			return;
		}
		//开始USB通信
		string m = USB.StartDevice();
		if( m != null ) {
			MessageBox.Show( m );
			OutputBox.ShowMessage( m );
			return;
		}
		//校验Flash
		if( ISP.CheckFlash( CodeBox.GetText() ) ) {
			OutputBox.ShowMessage( "Flash校验完成, 数据一致" );
		}
		else {
			string Mes = "Flash校验出错!";
			MessageBox.Show( Mes );
			OutputBox.ShowMessage( Mes );
		}
		//关闭USB设备
		USB.CloseDevice();
	}
	
	//自动操作
	void DownLoadButtonClick(object sender, EventArgs e)
	{
		Auto();
	}
	
	//读取芯片熔丝位
	void Button1Click(object sender, EventArgs e)
	{
		this.timer1.Enabled = true;
		
		this.label1.Text = "";
		this.label2.Text = "";
		this.label3.Text = "";
		this.label4.Text = "";
		this.label20.Text = "";
		this.label21.Text = "";
		this.label22.Text = "";
		this.label23.Text = "";
		this.label24.Text = "";
		this.Refresh();
		
		//打开USB设备
		string m = USB.StartDevice();
		if( m != null ) {
			MessageBox.Show( m );
			OutputBox.ShowMessage( m );
			return;
		}
		//读取芯片ID
		byte[] ID = ISP.ReadChipID();
		this.label1.Text = 	Convert.ToString( ID[ 0 ], 16 ).PadLeft( 2, '0' ) + ":" +
							Convert.ToString( ID[ 1 ], 16 ).PadLeft( 2, '0' ) + ":" +
							Convert.ToString( ID[ 2 ], 16 ).PadLeft( 2, '0' );
		//读取锁定位
		byte Lock = ISP.ReadLock();
		this.label2.Text = 	Convert.ToString( Lock, 16 ).PadLeft( 2, '0' );
		
		//读取熔丝位
		byte[] Fuse = ISP.ReadFuse();
		this.label3.Text = 	Convert.ToString( Fuse[ 0 ], 16 ).PadLeft( 2, '0' );
		this.label4.Text = 	Convert.ToString( Fuse[ 1 ], 16 ).PadLeft( 2, '0' );
		this.label20.Text =	Convert.ToString( Fuse[ 2 ], 16 ).PadLeft( 2, '0' );
		
		//读取时钟校正
		byte[] Clock = ISP.ReadClockBration();
		this.label21.Text = Convert.ToString( Clock[ 0 ], 16 ).PadLeft( 2, '0' );
		this.label22.Text = Convert.ToString( Clock[ 1 ], 16 ).PadLeft( 2, '0' );
		this.label23.Text =	Convert.ToString( Clock[ 2 ], 16 ).PadLeft( 2, '0' );
		this.label24.Text =	Convert.ToString( Clock[ 3 ], 16 ).PadLeft( 2, '0' );
		
		//关闭USB设备
		USB.CloseDevice();
	}
	
	//窗体关闭
	void Form1FormClosing(object sender, FormClosingEventArgs e)
	{
		if( SystemData.isChanged ) {
			SystemData.Save();
		}
		if( !isSelf ) {
			this.Visible = false;
			e.Cancel = true;
		}
	}

	//配置改变
	void ConfigChanged(object sender, EventArgs e)
	{
		if( !isLoad ) {
			return;
		}
		SystemData.isChanged = true;
		
		SystemData.ChangeLoad = this.DataChangeBox.Checked;
		SystemData.CheckID = this.CheckIDBox.Checked;
		SystemData.EraseFlash = this.EraseBox.Checked;
		SystemData.CheckEmpty = this.CheckEmptyBox.Checked;
		SystemData.WriteFlash = this.WriteFlashBox.Checked;
		SystemData.CheckFlash = this.CheckFlashBox.Checked;
	}
	
	//近期文件列表点击
 	void Button3Click(object sender, EventArgs e)
	{
 		LaterFileBox.Run();
	}
	
	//检查框重绘
	void CheckBoxPaint(object sender, PaintEventArgs e)
	{
		if( !( (CheckBox)sender ).Checked ) {
			return;
		}
		Rectangle r = new Rectangle( e.ClipRectangle.X + 1, e.ClipRectangle.Y + 6, 11, 11 );
		Pen p = new Pen( Color.Green, 2 );
		e.Graphics.DrawRectangle( p, r );
	}
	
	//下载按钮重绘
	void DownLoadButtonPaint(object sender, PaintEventArgs e)
	{
		e.Graphics.DrawImage( AutoIcon, 6, 6, e.ClipRectangle.Height - 12, e.ClipRectangle.Height - 12 );
	}
	
	//打开按钮重绘
	void OpenFileButtonPaint(object sender, PaintEventArgs e)
	{
		e.Graphics.DrawImage( OpenFileIcon, 6, 6, e.ClipRectangle.Height - 12, e.ClipRectangle.Height - 12 );
	}
	
	//近期文件按钮重绘
	void LaterFileButtonPaint(object sender, PaintEventArgs e)
	{
		e.Graphics.DrawImage( LaterFileIcon, 6, 6, e.ClipRectangle.Height - 12, e.ClipRectangle.Height - 12 );
	}
	
	//重载文件
	void ReloadFileButtonPaint(object sender, PaintEventArgs e)
	{
		e.Graphics.DrawImage( ReloadFileIcon, 6, 6, e.ClipRectangle.Height - 12, e.ClipRectangle.Height - 12 ) ;
	}
	
	//播放小人
	void Timer1Tick(object sender, EventArgs e)
	{
		++menIndex;
		menIndex %= men.Length;
		this.label25.Image = men[ menIndex ];
		
		if( menIndex == 0 ) {
			this.timer1.Enabled = false;
		}
	}
	
	//播放小喇叭
 	void Timer2Tick(object sender, EventArgs e)
	{
		++soundIndex;
		soundIndex %= sound.Length;
		this.label15.Image = sound[ soundIndex ];
		
		if( soundIndex == 0 ) {
			this.timer2.Enabled = false;
		}
	}
	
	void 芯片选择comboBoxSelectedIndexChanged(object sender, EventArgs e)
	{
		ChipList.SetChip( this.芯片选择comboBox.Text );
	}
    
    void Button写入熔丝Click(object sender, EventArgs e)
    {
    	if( MessageBox.Show( "您确定要修改熔丝吗? 菜鸟小弟们不要轻易修改哦, 可能锁住芯片的 :(", "修改熔丝确认", MessageBoxButtons.OKCancel ) == DialogResult.Cancel ) {
    		return;
    	}
    	byte low;
    	byte high;
    	try {
			low = byte.Parse( this.textBoxLow.Text, System.Globalization.NumberStyles.HexNumber );
			high = byte.Parse( this.textBoxHigh.Text, System.Globalization.NumberStyles.HexNumber );
		}
		catch {
			MessageBox.Show( "数据格式不正确, 应该输入字节型十六进制数据, 不需要前缀'0x'" );
			return;
		}
		//打开USB设备
		string m = USB.StartDevice();
		if( m != null ) {
			MessageBox.Show( m );
			OutputBox.ShowMessage( m );
			return;
		}
		//写入熔丝
		ISP.WriteFuse( low, high );
		
		//关闭USB设备
		USB.CloseDevice();
    }
}
//****************************************************************
//信息提示窗口
public static class OutputBox
{
	static Label OutputText;
	
	//初始化
	public static void Init( Label r )
	{
		OutputText = r;
	}
	
	//显示一行信息
	public static void ShowMessage( string Message )
	{
		T.ISPBox.timer2.Enabled = true;
		OutputText.Text = "";
		OutputText.Refresh();
		System.Threading.Thread.Sleep( 100 );
		OutputText.Text = Message;
		OutputText.Refresh();
	}
}
}
